The Box widgets

  • Box
  • FlexBox
  • Accordion
  • TabWidget

These widgets are used to provide a layout for placing other widgets.


In [ ]:
{-# LANGUAGE OverloadedStrings #-}
import IHaskell.Display.Widgets

These widgets have a Children field, which accepts a [ChildWidget]. A ChildWidget can be created using the ChildWidget constructor.


In [ ]:
:t ChildWidget

Box and FlexBox


In [ ]:
-- Create new Box and FlexBox
box <- mkBox
flx <- mkFlexBox

By default, boxes have a horizontal orientation. Thus adding some widgets to them lays them out horizontally.


In [ ]:
import Control.Monad (replicateM)

-- Make some buttons
buttons <- replicateM 20 mkButton

-- Add children widgets to boxes
let children = map ChildWidget buttons
setField box Children children
setField flx Children children

-- Display boxes
box
flx

You might be thinking that there is no difference between Box and FlexBox, but that's not true.

Following are some differences:

  • Box is always horizontal, whereas FlexBox has a configurable Orientation.
  • FlexBox is flexible, and the flexibility is determined by its Flex field (0 to 2).
  • FlexBox also has explicit Pack and Align fields.

Let's see these differences in action:


In [ ]:
-- Trying to set orientation for Boxes
setField box Orientation VerticalOrientation

The error means that the widget doesn't possess the Orientation property.


In [ ]:
-- Trying to set orientation for FlexBox
setField flx Orientation VerticalOrientation

ProxyWidget and PlaceProxy

The ProxyWidget widget allows for zero-or-one widgets to be placed inside it.

From the IHaskell perspective, this is similar to the Output widget, but supports only widgets inside it.


In [ ]:
[b1, b2, b3] <- replicateM 3 mkButton

setField b1 Description "Button 1"
setField b2 Description "Button 2"
setField b3 Description "Button 3"

-- A proxy widget to display one button at a time
proxy <- mkProxyWidget

-- b1 ~> b2
setField b1 ClickHandler $ setField proxy Child (Just $ ChildWidget b2)

-- b2 ~> b3
setField b2 ClickHandler $ setField proxy Child (Just $ ChildWidget b3)

-- b3 ~> b1
setField b3 ClickHandler $ setField proxy Child (Just $ ChildWidget b1)

-- Set initial child, and display
setField proxy Child (Just $ ChildWidget b1)

proxy

The PlaceProxy widget allows for more flexible use-cases involving arbitrary widgets. It is similar to ProxyWidget, but allows more control over where the widget is displayed.

This widget can be used to display widgets inside markdown cells, among other places such as custom widgets or custom html elements. For example, we can create a html div inside this markdown cell, and cause the child widget to display in it using its CSS selector.

<div id="widget_out"></div>


In [ ]:
pp <- mkPlaceProxy
button <- mkButton
setField button Description "(0,0)"

-- Put button inside the place proxy widget
setField pp Child (Just $ ChildWidget button)

-- Output to the div created above
setField pp Selector "#widget_out"

The widget doesn't yet display, but when we try to display it, the child widget shows in the div as expected.


In [ ]:
pp

Accordion and TabWidget

These widgets are useful for displaying a variety of content in a small amount of space.


In [ ]:
acc <- mkAccordion
tab <- mkTabWidget

Let's add some children and see what the result looks like.


In [ ]:
buttons' <- replicateM 5 mkButton

let children = map ChildWidget buttons'

setField acc Children children
setField tab Children children

acc
tab

Both the widgets are similar, the only major difference is in the orientation. Accordion is vertical, whereas TabWidget is horizontal.